package com.thinkingcoder.tcrpc.core.consumer.http;

import java.util.concurrent.TimeUnit;

import com.alibaba.fastjson.JSON;
import com.thinkingcoder.tcrpc.core.api.RpcRequest;
import com.thinkingcoder.tcrpc.core.api.RpcResponse;

import lombok.extern.slf4j.Slf4j;
import okhttp3.ConnectionPool;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;

@Slf4j
public class OkHttpInvoker implements HttpInvoker {
    final static MediaType JSON_TYPE = MediaType.get("application/json; charset=utf-8");

    OkHttpClient client;

    public OkHttpInvoker(int timeout) {
        client = new OkHttpClient.Builder().connectionPool(new ConnectionPool(16, 60, TimeUnit.SECONDS))
            .connectTimeout(timeout, TimeUnit.MILLISECONDS).readTimeout(timeout, TimeUnit.MILLISECONDS)
            .writeTimeout(timeout, TimeUnit.MILLISECONDS).retryOnConnectionFailure(true).build();
    }

    public RpcResponse<Object> post(RpcRequest rpcRequest, String url) {
        String repJson = JSON.toJSONString(rpcRequest);
        log.debug(" ===> reqJson = " + repJson);
        Request request = new Request.Builder().url(url).post(RequestBody.create(repJson, JSON_TYPE)).build();

        try {
            String respJson = client.newCall(request).execute().body().string();
            log.debug(" ===> respJson = " + respJson);
            RpcResponse<Object> response = JSON.parseObject(respJson, RpcResponse.class);
            return response;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public String post(String url, String body) {
        log.debug(" ===> post url = {}, body = {}", url, body);
        Request request = new Request.Builder().url(url).post(RequestBody.create(JSON_TYPE, body)).build();
        try {
            String respJson = client.newCall(request).execute().body().string();
            log.debug(" ===> respJson = " + respJson);
            return respJson;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public String get(String url) {
        log.debug(" ===> get url = {}", url);
        Request request = new Request.Builder().url(url).get().build();
        try {
            String respJson = client.newCall(request).execute().body().string();
            log.debug(" ===> respJson = " + respJson);
            return respJson;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
